//
//  TVTextField.swift
//  iPhone
//
//  Created by Toj on 8/28/22.
//

import UIKit

enum TVTextFieldStyle {
    case titleLeft
    case titleTop
}

protocol TVTextFieldDelegate: NSObjectProtocol {
    func textFieldEditingChange(_ view: TVTextField, text: String, validText: String)
}

extension TVTextFieldDelegate {
    func textFieldEditingChange(_ view: TVTextField, text: String, validText: String) { }
}

class TVTextField: UIView {
    
    weak var delegate: TVTextFieldDelegate?
    
    var style: TVTextFieldStyle = .titleTop
    
    var lineHeight: CGFloat = 1
    var charFormatType: String.SPFormatterType = .none
    var maxCharCount = 0 { didSet {
        guard maxCharCount > 0 else {
            maxCharLabel.isHidden = true
            return
        }
        maxCharLabel.isHidden = false
        maxCharLabel.text = "0/\(maxCharCount)"
    } }
    
    var textSeparator = " "
    
    var validText: String {
        get {
            if textSeparator.isEmpty { return text }
            return text.replacingOccurrences(of: textSeparator, with: "")
        }
        
        set {
            textField.text = newValue
            textFieldEditingChange(with: textField)
        }
    }
    var text: String {
        get {
            return textField.text ?? ""
        }
        
        set {
            textField.text = newValue
        }
    }
    
    @objc private func textFieldEditingChange(with sender: UITextField) {
        
        guard var string = sender.text?.replacingOccurrences(of: textSeparator, with: "") else {
            maxCharLabel.text = "0/\(maxCharCount)"
            delegate?.textFieldEditingChange(self, text: "", validText: "")
            return
        }
        
        if string.count > maxCharCount {
            let startIndex = string.startIndex
            let middleIndex = string.index(startIndex, offsetBy: maxCharCount)
            let range = middleIndex..<string.endIndex
            string.removeSubrange(range)
        }
        
        let count = string.count
        maxCharLabel.text = "\(count)/\(maxCharCount)"
        let text = string.cm_numberFormat(format: charFormatType, separator: textSeparator)
        
        sender.text = text
        delegate?.textFieldEditingChange(self, text: text, validText: string)
    }
    
    
    var rightView: UIView? = nil { didSet {
        guard let view = rightView else { return }
        addSubview(view)
    } }
    
    private(set) lazy var titleLabel: UILabel = {
        let view = UILabel()
        return view
    }()
    
    private(set) lazy var textField: UITextField = {
        let view = STTextField()
        view.isSecureTextEntry
        view.isDisableCopy = true
        view.backgroundColor = .clear
        // 边框
        view.borderStyle = .none
        // 是否纠错
        view.autocorrectionType = .no
        // 首字母大写
        view.autocapitalizationType = .none
        
        view.delegate = self
        return view
    }()
    
    private(set) lazy var lineView: UIView = {
        let view = UIView()
        view.backgroundColor = "#DDDDDD".to_color
        return view
    }()
    
    private(set) lazy var maxCharLabel: UILabel = {
        let view = UILabel()
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupMakeAddSubviews()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        setupMakeLayoutSubviews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private let defaultFont = UIFont.systemFont(ofSize: 12)
}

// MARK: - 初始化
extension TVTextField {
    
    private func setupMakeAddSubviews() {
        
        addSubview(titleLabel)
        addSubview(textField)
        addSubview(lineView)
        addSubview(maxCharLabel)
    }
    
    private func setupMakeLayoutSubviews() {
        var height = CGFloat.zero
        if maxCharCount > 0 {
            height = "9/9".cm_stringOneLineHeight(font: maxCharLabel.font)
            maxCharLabel.snp.makeConstraints { make in
                make.bottom.right.equalTo(self)
                make.height.equalTo(height)
            }
        }
        let bottom = height > 0 ? (height + 8) : 0
        lineView.snp.makeConstraints { (make) in
            make.left.right.equalTo(self)
            make.height.equalTo(lineHeight)
            make.bottom.equalTo(-bottom)
        }
        
        if style == .titleTop {
            titleLabel.snp.makeConstraints { (make) in
                make.top.left.right.equalTo(self)
            }
            
            var size = CGSize.zero
            if let view = rightView {
                size = view.frame.size
            }
            let right = size.width + 5 // margin = 5
            let font = textField.font ?? defaultFont
            height = "9".cm_stringOneLineHeight(font: font)
            textField.snp.makeConstraints { (make) in
                make.left.equalTo(self)
                make.top.equalTo(titleLabel.snp.bottom).offset(12)
                make.height.equalTo(height)
                make.right.equalTo(-right)
            }
            
            rightView?.snp.makeConstraints { make in
                make.right.equalTo(self)
                make.centerY.equalTo(textField)
                make.height.equalTo(size.height)
                make.width.equalTo(size.width)
            }
            return
        }
        
        titleLabel.snp.makeConstraints { (make) in
            make.left.top.equalTo(self)
            make.bottom.equalTo(lineView.snp.top)
        }
        
        var size = CGSize.zero
        if let view = rightView {
            size = view.frame.size
        }
        let right = size.width + 5 // margin = 5
        let font = textField.font ?? defaultFont
        height = "9".cm_stringOneLineHeight(font: font)
        textField.snp.makeConstraints { (make) in
            make.left.equalTo(titleLabel.snp.right).offset(5)
            make.centerY.equalTo(titleLabel)
            make.height.equalTo(height)
            make.right.equalTo(-right)
        }
        
        rightView?.snp.makeConstraints { make in
            make.right.equalTo(self)
            make.centerY.equalTo(textField)
            make.height.equalTo(size.height)
            make.width.equalTo(size.width)
        }
    }
}

extension TVTextField: UITextFieldDelegate {
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        // 删除
        if string.isEmpty {
            return textField.delete(shouldChangeCharactersIn: range, replacementString: string, maxLength: maxCharCount, formatType: charFormatType, separator: textSeparator)
        }
        
        // 非数字过滤掉, 系统有个bug 如果返回false光标也跳转count位
        guard string.rx_isValidNumber else {
            return false
        }
        
        // 输入
        return textField.insert(shouldChangeCharactersIn: range, replacementString: string, maxLength: maxCharCount, formatType: charFormatType, separator: textSeparator)
    }
}

private let disableSelector: [Selector] = [
    #selector(UIResponderStandardEditActions.paste(_:)),
    #selector(UIResponderStandardEditActions.select(_:)),
    #selector(UIResponderStandardEditActions.selectAll(_:))
]

open class STTextField: UITextField {
    
    public var isDisableCopy = false
    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if isDisableCopy {
            if disableSelector.contains(action) { return false }
        }
        return super.canPerformAction(action, withSender: sender)
    }
}
